
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.applet.Applet;
import java.awt.Color;
import java.awt.GraphicsEnvironment;
import java.awt.image.BufferedImage;

public class World extends JFrame implements KeyListener {

    Map map = new Map(25, 25);
    ImageManager im = new ImageManager();
    public int camera_x = 10, camera_y = 10;
    Entity player = new EntityPlayer(15, 15, 10, null);
    BufferedImage off = new BufferedImage(650, 650, BufferedImage.TYPE_INT_ARGB);
    Graphics back = off.getGraphics();

    World() {

        this.setSize(800, 800);
        this.setVisible(true);
        addKeyListener(this);
        repaint();
    }

    public void update(Graphics g) {
        paint(g);
    }

    public void paintMap() {
        back.setColor(Color.BLACK);
        for (int z = camera_x - 10, i = 0; z < camera_x + 10; z++, i++) {

            for (int v = camera_y - 10, j = 0; v < camera_y + 10; v++, j++) {

                for (int ids = 0; ids < Globals.NUM_IDS; ids++) {
                    if (ids == map.get(z, v)) {
                        back.drawImage(im.IMAGES[ids], i * Globals.SPRITE_SIZE, j * Globals.SPRITE_SIZE, null);
                        back.drawRoundRect(i * Globals.SPRITE_SIZE, j * Globals.SPRITE_SIZE, Globals.SPRITE_SIZE, Globals.SPRITE_SIZE, 0, 0);
                        break;
                    }
                }

            }
        }
    }

    public void paint(Graphics g) {
        back.clearRect(0, 0, off.getHeight(rootPane), off.getWidth(rootPane));
        paintMap();
        paintPlayer();
        g.drawImage(off, 0, 0, rootPane);
    }

    public void paintPlayer() {
        back.setColor(Color.BLACK);
        for (int z = camera_x - 10, i = 0; z < camera_x + 10; z++, i++) {
            for (int v = camera_y - 10, j = 0; v < camera_y + 10; v++, j++) {
                if (Math.floor(player.x) == z && Math.floor(player.y) == v) {
                    back.fillRoundRect(i * Globals.SPRITE_SIZE + ((int) ((player.x - z) * Globals.SPRITE_SIZE)),
                            j * Globals.SPRITE_SIZE + ((int) ((player.y - v) * Globals.SPRITE_SIZE)),
                            Globals.SPRITE_SIZE, Globals.SPRITE_SIZE, 45, 45);
                }
            }
        }

    }

    public int updateCameraX() {
        int totalx = camera_x - (int) Math.round(player.x);
        if (totalx > Globals.TOPLEFT) {
            int temp = camera_x - (totalx - Globals.TOPLEFT);
            if (temp < 10) {
                return 10;
            } else {
                return temp;
            }
        } else if (totalx < Globals.BOTTOMRIGHT * -1) {
            int temp = camera_x + (Math.abs(totalx) - Globals.BOTTOMRIGHT);
            if (temp > map.x - 10) {
                return map.x - 10;
            } else {
                return temp;
            }
        } else {
            return camera_x;
        }
    }

    public int updateCameraY() {
        int totaly = camera_y - (int) Math.round(player.y);
        if (totaly > Globals.TOPLEFT) {
            int temp = camera_y - (totaly - Globals.TOPLEFT);
            if (temp < 10) {
                return 10;
            } else {
                return camera_y - (totaly - Globals.TOPLEFT);
            }
        } else if (totaly < -5) {
            int temp = camera_y + (Math.abs(totaly) - Globals.BOTTOMRIGHT);
            if (temp > map.y - 10) {
                return map.y - 10;
            } else {
                return camera_y + (Math.abs(totaly) - Globals.BOTTOMRIGHT);
            }
        } else {
            return camera_y;
        }
    }

    public void movement(String move) {

        String[] moves = move.split(":");
        double x = player.x;
        double y = player.y;
        if (moves[0].contains("x")) {
            x += move.contains("+") ? .25 : -.25;
        }
        if (moves[1].contains("y")) {
            y += move.contains("+") ? .25 : -.25;
        }

        int[] newx_coords = new int[2];//x spaces the player is in
        int[] newy_coords = new int[2];//y spaces the player is in
        if (x == Math.floor(x)) {
            newx_coords[0] = (int) x;
            newx_coords[1] = (int) x;
        } else {
            newx_coords[0] = (int) Math.floor(x);
            newx_coords[1] = (int) Math.floor(x) + 1;
        }
        if (y == Math.floor(y)) {
            newy_coords[0] = (int) y;
            newy_coords[1] = (int) y;
        } else {
            newy_coords[0] = (int) Math.floor(y);
            newy_coords[1] = (int) Math.floor(y) + 1;
        }

        boolean canMove = true;
        for (int z = 0; z < 2; z++) {
            for (int v = 0; v < 2; v++) {
                if (map.get(newx_coords[z], newy_coords[v]) != Globals.GRASS) {
                    canMove = false;
                }
            }
        }
        if (canMove) {
            player.x = x;
            player.y = y;
        }

    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_F5) {
            System.out.println("refreshing");
            repaint();
        }
        if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
            System.exit(0);
        }
        if (e.getKeyCode() == KeyEvent.VK_UP) {
            movement("null:y-");
        } else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
            movement("null:y+");
        } else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            movement("x+:null");
        } else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
            movement("x-:null");
        }
        camera_x = updateCameraX();
        camera_y = updateCameraY();
        repaint();
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }
}
